package com.cskaoyan.javase.oop3._2inner._3local._1use;

/**
 * 局部内部类的访问特点，我们仍然主要从以下几个角度研究：
 *      1.局部内部类内部访问外围类(重点)
 *      2.外围类访问局部内部类成员(重点)
 *      3.外部类访问局部内部类成员
 *          首先肯定是不可能直接访问的
 *          因为出了作用域,局部内部类就不再生效了
 *      4.局部内部类访问外部类成员
 *          仍然需要创建对象,仍然受权限限制
 *
 * 定义在局部位置的局部内部类,以方法内部的局部内部类为案例
 * 可以分成两种情况,局部内部类访问外围类成员:
 *      1.定义在外围类的成员方法中的局部内部类
 *          和成员内部类类似
 *          局部内部类对象,会持有外围类对象的引用作为自身成员变量
 *          访问不受权限限制
 *          这时的访问和成员内部类访问外围类基本就是一样的
 *
 *      2.定义在外围类的静态成员方法中的局部内部类
 *          和静态内部类类似
 *          因为没有任何对象可以持有
 *          所以这时的局部内部类对象,不会持有外围类对象的引用.
 *
 * 那么在外围类当中,如何访问局部内部类成员呢?
 * 首先要注意,局部内部类仅在作用域内部生效
 * 出了作用域,其他位置是不能直接访问的
 * 所以必须在作用域下面直接创建局部内部类对象去访问成员,然后访问也不受权限的限制
 *
 *
 * @since 14:26
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        /*EnclosedClazz ec = new EnclosedClazz();
        ec.test();*/
        EnclosedClazz.testStatic();
    }
}

class EnclosedClazz {
    int a;
    private int b = 10;
    static int c = 20;
    static final int D = 30;
    // 外围类的成员方法,隐含this传参指向外围类对象
    public void test() {
        // 外围类的成员方法中的局部内部类
        class Inner {
            int a;
            private int b = 10;
            static final int D = 30;
            // 外围类的成员方法中的局部内部类中的成员方法
            public void testInner() {
                /*
                    这里已经存在this指向当前局部内部类对象
                    还会持有一个外围类对象
                    外围类对象用"外围类类名.this"指向
                  */
                System.out.println(a);
                System.out.println(b);
                System.out.println(EnclosedClazz.this.a);
                System.out.println(EnclosedClazz.this.b);
            }
        }
        Inner in = new Inner();
        System.out.println(in.a);
        System.out.println(in.b);
        in.testInner();
    }

    // 外围类的静态成员方法,没有任何对象
    public static void testStatic() {
        // 外围类的静态成员方法中的局部内部类
        class Inner {
            int a;
            private int b = 10;
            public void testInner(){
                // 仍然有一个对象,this指向自身局部内部类对象,除此之外没有别的对象了
                System.out.println(a);
                System.out.println(b);
                EnclosedClazz ec = new EnclosedClazz();
                System.out.println(ec.a);
                System.out.println(ec.b);
            }
        }
        Inner in = new Inner();
        System.out.println(in.a);
        System.out.println(in.b);
        in.testInner();
    }
}